package com.syh.jn.scm.domain.supplier.entity.base.upstream;

import cn.redscarf.commons.util.bean.ExtBeanUtils;
import cn.redscarf.commons.util.other.ExtAssert;
import cn.redscarf.commons.spring.SpringContextUtils;
import cn.redscarf.commons.util.validator.ValidationUtils;
import cn.redscarf.commons.wrapper.Restrictions;
import cn.redscarf.commons.wrapper.Wrapper;
import com.syh.core.ddd.domain.AbstractSimpleAggregate;
import com.syh.core.ddd.domain.CodeExpEnum;
import com.syh.core.ddd.domain.CodeGenerateUtil;
import com.syh.jn.scm.domain.supplier.repository.base.upstream.UpstreamCategoryReadRepository;
import com.syh.jn.scm.domain.supplier.repository.finance.*;
import com.syh.jn.scm.domain.supplier.repository.purchase.PurReturnOrderReadRepository;
import com.syh.jn.scm.domain.supplier.repository.purchase.PurchaseOrderReadRepository;
import com.syh.jn.scm.domain.upstream.repository.base.UpBusinessEntityExtGoodsInfoReadRepository;
import com.syh.jn.scm.domain.upstream.repository.base.UpBusinessEntityGoodsOfferReadRepository;
import com.syh.jn.scm.dto.supplier.base.upstream.supplier.UpstreamMto;
import com.syh.jn.scm.dto.supplier.base.upstream.supplier.UpstreamSto;
import com.syh.jn.scm.dto.supplier.base.upstream.supplierAddress.UpstreamAddressSto;
import com.syh.jn.scm.exception.BusinessException;
import lombok.Data;
import lombok.EqualsAndHashCode;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

/**
 * 上游供应商
 */
@Data
@EqualsAndHashCode(callSuper = true)
public class Upstream extends AbstractSimpleAggregate<Long> {
  /**
   * 新建上游供应商
   *
   * @param dto
   * @return
   */
  public static Upstream createBusiness(UpstreamSto dto) {
    ExtAssert.notNull(dto, "对象为空");
    ValidationUtils.validate(dto);
    Upstream upStream = Upstream.systemCreate(dto);
    upStream.setUuid(UUID.randomUUID().toString());
    upStream.setCode(CodeGenerateUtil.merchantCodeGenerate(CodeExpEnum.UPSTREAM_CODE_EXP.getCodeExp()));
    upStream.setAddressesItem(new ArrayList<>());
    dto.getAddressListSto().stream().forEach((addressSto) -> {
      upStream.addAddressItems(UpstreamAddress.create(addressSto));
    });
    return upStream;
  }

  /**
   * 修改上游供应商
   *
   * @param mto
   */
  public void modify(UpstreamMto mto) {
    ExtAssert.notNull(mto, "对象为空");
    ValidationUtils.validate(mto);
    ExtBeanUtils.copyProperties(mto, this);
    //code不符合规则则重新生成code
    if (!CodeGenerateUtil.checkExp(CodeExpEnum.UPSTREAM_CODE_EXP.getCodeRegexp(), this.code)) {
      this.code = CodeGenerateUtil.merchantCodeGenerate(CodeExpEnum.UPSTREAM_CODE_EXP.getCodeExp());
    }
    this.addressesItem = new ArrayList<>();

    mto.getAddressListMto().stream().forEach((addressMto) -> {
      UpstreamAddressSto sto = ExtBeanUtils.copyProperties(addressMto, new UpstreamAddressSto(), true);
      UpstreamAddress upstreamAddress = UpstreamAddress.create(sto);
      this.addressesItem.add(upstreamAddress);
    });


    this.lastUpdateTimeStamp = System.currentTimeMillis();
  }

  /**
   * 启用供应商
   */
  public void enabled() {
    UpstreamCategoryReadRepository upCateRead = (UpstreamCategoryReadRepository) SpringContextUtils.getBean(UpstreamCategoryReadRepository.class);
    UpstreamCategory upCate = upCateRead.getById(this.categoryId);
    if (!upCate.getStatus().equals(Short.valueOf("1")))
      throw new BusinessException("该供应商分类未启用！请先启用分类");
    this.status = 1;
  }

  /**
   * 停用供应商
   */
  public void disabled() {
    this.status = -1;
  }

  /**
   * 系统默认的字段值
   *
   * @return
   */
  private static Upstream systemCreate(UpstreamSto dto) {
    Upstream upStream = new Upstream();
    ExtBeanUtils.copyProperties(dto, upStream);
    upStream.status = Short.valueOf("1");
    upStream.createTimeStamp = System.currentTimeMillis();
    upStream.createDateTimestamp = System.currentTimeMillis();
    return upStream;
  }

  /**
   * 增加地址项
   *
   * @param item
   * @return
   */
  public Upstream addAddressItems(UpstreamAddress item) {
    this.addressesItem.add(item);
    return this;
  }

  /**
   * 数据销毁
   */
  public void destroy() {
    //查看采购是否有数据存在
    PurchaseOrderReadRepository purchase = (PurchaseOrderReadRepository) SpringContextUtils.getBean("purchaseOrderRepositoryImpl");
    Wrapper purchaseWrapper = Wrapper.build();
    purchaseWrapper.append(Restrictions.eq("upStreamCompanyId", this.id));
    Integer purchaseCount = purchase.getCount(purchaseWrapper);
    if (purchaseCount > 0) {
      throw new BusinessException("采购单存在该数据,删除失败");
    }
    //查看采购退货是否有数据存在
    PurReturnOrderReadRepository purchaseReturn = (PurReturnOrderReadRepository) SpringContextUtils.getBean(PurReturnOrderReadRepository.class);
    Wrapper purchaseReturnWrapper = Wrapper.build();
    purchaseReturnWrapper.append(Restrictions.eq("upStreamCompanyId", this.id));
    Integer purchaseReturnCount = purchaseReturn.getCount(purchaseReturnWrapper);
    if (purchaseReturnCount > 0) {
      throw new BusinessException("采购退货单存在该数据,删除失败");
    }
    //查看对账单是否有数据存在
    StatementAccountBillReadRepository statementBill = (StatementAccountBillReadRepository) SpringContextUtils.getBean(StatementAccountBillReadRepository.class);
    Wrapper statementBillWrapper = Wrapper.build();
    statementBillWrapper.append(Restrictions.eq("customerId", this.id));
    statementBillWrapper.append(Restrictions.eq("customerType", Short.valueOf("0")));
    Integer statementCount = statementBill.getCount(statementBillWrapper);
    if (statementCount > 0) {
      throw new BusinessException("对账单存在该数据,删除失败");
    }
    //查看费用单是否有数据存在
    CostBillReadRepository costBill = (CostBillReadRepository) SpringContextUtils.getBean(CostBillReadRepository.class);
    Wrapper costBillWrapper = Wrapper.build();
    costBillWrapper.append(Restrictions.eq("customerId", this.id));
    costBillWrapper.append(Restrictions.eq("customerType", Short.valueOf("0")));
    Integer costCount = costBill.getCount(costBillWrapper);
    if (costCount > 0) {
      throw new BusinessException("费用单存在该数据,删除失败");
    }
    //查看收入单是否有数据存在
    IncomeBillReadRepository incomeBill = (IncomeBillReadRepository) SpringContextUtils.getBean(IncomeBillReadRepository.class);
    Wrapper incomeBillWrapper = Wrapper.build();
    incomeBillWrapper.append(Restrictions.eq("customerId", this.id));
    incomeBillWrapper.append(Restrictions.eq("customerType", Short.valueOf("0")));
    Integer incomeCount = incomeBill.getCount(incomeBillWrapper);
    if (incomeCount > 0) {
      throw new BusinessException("收入单存在该数据,删除失败");
    }
    //查看收款单是否有数据存在
    ReceiptBillReadRepository receiptBill = (ReceiptBillReadRepository) SpringContextUtils.getBean(ReceiptBillReadRepository.class);
    Wrapper receiptBillWrapper = Wrapper.build();
    receiptBillWrapper.append(Restrictions.eq("customerId", this.id));
    receiptBillWrapper.append(Restrictions.eq("customerType", Short.valueOf("0")));
    Integer receiptCount = receiptBill.getCount(receiptBillWrapper);
    if (receiptCount > 0) {
      throw new BusinessException("收款单存在该数据,删除失败");
    }
    //查看付款单是否有数据存在
    PaymentBillReadRepository paymentBill = (PaymentBillReadRepository) SpringContextUtils.getBean(PaymentBillReadRepository.class);
    Wrapper paymentBillWrapper = Wrapper.build();
    paymentBillWrapper.append(Restrictions.eq("customerId", this.id));
    paymentBillWrapper.append(Restrictions.eq("customerType", Short.valueOf("0")));
    Integer paymentCount = paymentBill.getCount(paymentBillWrapper);
    if (paymentCount > 0) {
      throw new BusinessException("付款单存在该数据,删除失败");
    }
    //扩展编码是否有数据
    UpBusinessEntityExtGoodsInfoReadRepository goodsExtCodeReadRepository = (UpBusinessEntityExtGoodsInfoReadRepository) SpringContextUtils.getBean(UpBusinessEntityExtGoodsInfoReadRepository.class);
    Wrapper goodsExtCodeWrapper = Wrapper.build();
    goodsExtCodeWrapper.append(Restrictions.eq("businessEntityId", this.id));
    Integer goodsExtCount = goodsExtCodeReadRepository.getCount(goodsExtCodeWrapper);
    if (goodsExtCount > 0) {
      throw new BusinessException("该上游存在对商品填写了扩展编码,删除失败");
    }
    //商品报价是否有数据
    UpBusinessEntityGoodsOfferReadRepository goodsOfferReadRepository = (UpBusinessEntityGoodsOfferReadRepository) SpringContextUtils.getBean(UpBusinessEntityGoodsOfferReadRepository.class);
    Wrapper goodsOfferWrapper = Wrapper.build();
    goodsOfferWrapper.append(Restrictions.eq("businessEntityId", this.id));
    Integer goodsOfferCount = goodsOfferReadRepository.getCount(goodsOfferWrapper);
    if (goodsOfferCount > 0) {
      throw new BusinessException("该上游存在对商品进行过报价,删除失败");
    }
  }

  /**
   * 分类id
   */
  private Long categoryId;
  /**
   * 所属种类,应用分类编码
   */
  private String categoryCode;
  /**
   * 地址省 市 区
   */
  private String area;
  /**
   * 归属id
   */
  private Long businessEntityId;
  /**
   * 单位注册地址
   */
  private String address;
  /**
   * 地区编号
   */
  private String areaCode;
  /**
   * 单位编号
   */
  private String code;
  /**
   * 单位名称
   */
  private String name;
  /**
   * 法人代表
   */
  private String legalRepresentative;
  /**
   * 注册资金（单位 ：万元）
   */
  private Integer registeredCapital;
  /**
   * 纳税识别号
   */
  private String registrationCode;
  /**
   * 状态: -1停用, 1可用
   */
  private Short status;
  /**
   * 对公电子邮件
   */
  private String email;
  /**
   * 公司联系电话
   */
  private String tel;
  /**
   * 纳税人类型: 1：一般纳税人 2：小规模纳税人
   */
  private Short taxpayer;
  /**
   * 创建日期
   */
  private Long createDateTimestamp;
  /**
   * 营业执照图片url,保存格式json字符串{"img":"www.test.com","img":"www.demo.com"}
   */
  private String businessLicense;
  /**
   * 地址项
   */
  private List<UpstreamAddress> addressesItem;
  /**
   * 期初应收总额
   */
  private BigDecimal beginReceiveTotalAmount;
  /**
   * 期初应付总额
   */
  private BigDecimal beginPaymentTotalAmount;
}
